﻿// SyntheticDataGenerator.Core.TaxonomyPatternSet
//
// (c) 2011 Arthur Pitman
//
// Part of Market-Basket Synthetic Data Generator
// A C# adaptation of the IBM Quest Market-Basket Synthetic Data Generator
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// (Version 2) as published by the Free Software Foundation.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License (Version 2) along with this program; if not, write to 
// the Free Software Foundation, Inc., 
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// or see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SyntheticDataGenerator.ParameterSets;

namespace SyntheticDataGenerator.Core
{
	/// <summary>
	/// Taxonomy pattern set
	/// </summary>
	public class TaxonomyPatternSet : PatternSet
	{
		/// <summary>
		/// Initializes a new <see cref="TaxonomyPatternSet"/> instance based on the specified <see cref="Taxonomy"/>
		/// </summary>
		/// <param name="itemCount"></param>
		/// <param name="patternParameters"></param>
		/// <param name="taxonomy"></param>
		/// <param name="repetitionLevel"></param>
		/// <param name="repetitionVariance"></param>
		public TaxonomyPatternSet(int itemCount, PatternParameters patternParameters, Taxonomy taxonomy, double repetitionLevel = 0, double repetitionVariance = 0.2)
			: base(new TaxonomyItemSet(itemCount, taxonomy), patternParameters, repetitionLevel, repetitionVariance)
		{
			// weight probabilites with geometric mean of probabilities of items
			for (int i = 0; i < PatternCount; i++)
			{
				double weight = 1;
				for (int j = 0; j < patterns[i].Items.Length; j++)
					weight *= items.GetWeight(patterns[i].Items[j]);
				weight = Math.Pow(weight, 1.0 / patterns[i].Items.Length);
				patterns[i].Probability *= weight;
			}

			CalculateProbabilities();
		}

		// returns pattern #i
		/// <summary>
		/// Gets a <see cref="Pattern"/> by index
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		public override Pattern GetPattern(int index)
		{
			Pattern specializedString = new Pattern(patterns[index].Items.Length, 0, patterns[index].Confidence);
			
			for (int j = 0; j < patterns[index].Items.Length; j++)
				specializedString.Items[j] = ((TaxonomyItemSet)items).Specialize(patterns[index].Items[j]);
			return specializedString;
		}
	}
}
